using micromsg;
using MicroMsg.Common.Event;
using MicroMsg.Common.Utils;
using MicroMsg.Manager;
using MicroMsg.Protocol;
using MicroMsg.Storage;
using System;
using System.Collections.Generic;
namespace MicroMsg.Scene
{
	public class NetSceneNewInit : NetSceneBaseEx<NewInitRequest, NewInitResponse, NewInitRequest.Builder>
	{
		public delegate bool ProcessCmdItemDelegate(NewInitRequest request, NewInitResponse response, List<object> cmdObjectList);
		private const string TAG = "NetSceneNewInit";
		public const int MAX_INIT_COUNT = 50;
		public const int MAX_RETRY_COUNT = 3;
		private EventWatcher mWatcher;
		private int mInitCount;
		private int mSelector;
		private int mScene = 3;
		private static int mInitStatus = 0;
		private static byte[] mInitCurrentSynckey = null;
		private static byte[] mInitMaxSynckey = null;
		private uint mProgress;
		private static List<CmdItem> mCmdList = new List<CmdItem>();
		public uint progress
		{
			get
			{
				return this.mProgress;
			}
		}
		public NetSceneNewInit()
		{
			this.mWatcher = new EventWatcher(this, null, new EventHandlerDelegate(NetSceneNewInit.onEventHandler));
			EventCenter.registerEventWatcher(EventConst.ON_NETSCENE_AUTH_SUCCESS, this.mWatcher);
		}
		public static void onLoginHandler()
		{
			AccountMgr.mInitRetryTimes = 0;
			if (AccountMgr.getCurAccount().nInitStatus != 1)
			{
				NetSceneNewInit.mInitStatus = 0;
			}
			else
			{
				NetSceneNewInit.mInitStatus = 1;
			}
			NetSceneNewInit.mInitCurrentSynckey = AccountMgr.getCurAccount().bytesCurSyncKey;
			NetSceneNewInit.mInitMaxSynckey = AccountMgr.getCurAccount().bytesMaxSyncKey;
		}
		public bool doScene()
		{
			Log.smethod_4("NetSceneNewInit", "newInit doscene begin");
			EventCenter.postEvent(EventConst.ON_NETSCENE_PROCESS_NEWINIT_BEGIN, null, null);
			NetSceneNewInit.mInitStatus = 2;
			this.mSelector = 7;
			Account curAccount = AccountMgr.getCurAccount();
			if (curAccount.nNewUser != 0 && (NetSceneNewInit.mInitCurrentSynckey == null || NetSceneNewInit.mInitCurrentSynckey.Length == 0))
			{
				this.mScene = 7;
			}
			else
			{
				if (NetSceneNewInit.mInitCurrentSynckey != null && NetSceneNewInit.mInitCurrentSynckey.Length != 0)
				{
					this.mScene = 4;
				}
				else
				{
					this.mScene = 3;
				}
			}
			return this.continueDoScene();
		}
		private bool continueDoScene()
		{
			base.beginBuilder();
			this.mBuilder.BaseRequest = NetSceneBase.makeBaseRequest(this.mScene);
			this.mBuilder.UserName = AccountMgr.getCurAccount().strUsrName;
			this.mBuilder.CurrentSynckey = Util.toSKBuffer(NetSceneNewInit.mInitCurrentSynckey);
			this.mBuilder.MaxSynckey = Util.toSKBuffer(NetSceneNewInit.mInitMaxSynckey);
			this.mSessionPack.mCmdID = 27;
			base.endBuilder();
			if (this.mInitCount < 50)
			{
				this.mInitCount++;
			}
			else
			{
				Log.smethod_5("NetSceneNewInit", "mInitCount exceed the maximum");
			}
			this.mProgress = 10u;
			return true;
		}
		protected override void onSuccess(NewInitRequest request, NewInitResponse response)
		{
			Log.smethod_4("NetSceneNewInit", string.Concat(new object[]
			{
				"newInit doscene onSuccess!initresp.selectBitmap:",
				response.SelectBitmap,
				" response.ContinueFlag=",
				response.ContinueFlag
			}));
			RetConst ret = (RetConst)response.BaseResponse.Ret;
			if (ret != RetConst.MM_OK)
			{
				Log.smethod_1("NetSceneNewInit", "deal With NewSyncResponse: NewInit failed! ret = " + ret);
				NetSceneNewInit.mInitStatus = 0;
				this.resetFlag();
				EventCenter.postEvent(EventConst.ON_NETSCENE_PROCESS_NEWINIT_ERR, null, null);
				return;
			}
			NetSceneNewInit.mCmdList.AddRange(response.CmdListList);
			this.ProcessCmdItem(request, response);
		}
		private bool ProcessCmdItem(NewInitRequest request, NewInitResponse response)
		{
			if (!this.saveUserInfo(request, response))
			{
				Log.smethod_5("NetSceneNewInit", "SaveUserInfo failed");
			}
			if (this.canContinue(response))
			{
				Log.smethod_4("NetSceneNewInit", "newInit doscene continue");
				this.mProgress = response.Ratio;
				this.continueDoScene();
				return true;
			}
			Log.smethod_4("NetSceneNewInit", string.Concat(new object[]
			{
				"newInit doscene finished! init end, initresp.selectBitmap:",
				response.SelectBitmap,
				" response.ContinueFlag=",
				response.ContinueFlag
			}));
			this.mProgress = 70u;
			List<object> cmdObjectList = NetSceneNewSync.getCmdObjectList(NetSceneNewInit.mCmdList);
			this.ProcessCmdItemByGroup(cmdObjectList);
			this.mProgress = 90u;
			this.resetFlag();
			NetSceneNewInit.mInitStatus = 1;
			SyncInfo info = new SyncInfo(NetSceneNewInit.mInitCurrentSynckey, NetSceneNewInit.mInitMaxSynckey, NetSceneNewSync.mBytesSyncKeyBuf, NetSceneNewInit.mInitStatus);
			AccountMgr.saveSyncInfoAsync(info);
			Log.smethod_4("NetSceneNewInit", "newInit doscene save accinfo(include bytesSyncKeyBuf) success");
			if (this.needInit())
			{
				AccountMgr.mInitRetryTimes++;
				if (AccountMgr.mInitRetryTimes > 3)
				{
					Log.smethod_1("NetSceneNewInit", "newInit doscene NewInit failed! mInitRetryTimes reach MAX_RETRY_COUNT=3");
					NetSceneNewInit.mInitStatus = 0;
					EventCenter.postEvent(EventConst.ON_NETSCENE_PROCESS_NEWINIT_ERR, null, null);
					return false;
				}
				Log.smethod_5("NetSceneNewInit", "newInit doscene err,retry newinit. mInitRetryTimes = " + AccountMgr.mInitRetryTimes);
			}
			else
			{
				Log.smethod_5("NetSceneNewInit", "newInit doscene success");
				this.mProgress = 100u;
				EventCenter.postEvent(EventConst.ON_NETSCENE_PROCESS_NEWINIT_FINISH, null, null);
			}
			ServiceCenter.sceneNewSync.doScene(2, syncScene.MM_NEWSYNC_SCENE_AFTERINIT);
			return true;
		}
		private void ProcessCmdItemByGroup(List<object> cmdObjectList)
		{
			List<object> list = new List<object>();
			List<object> list2 = new List<object>();
			List<object> list3 = new List<object>();
			List<object> list4 = new List<object>();
			Log.smethod_4("NetSceneNewInit", "newInit doscene ,ProcessCmdItemByGroup");
			using (List<object>.Enumerator enumerator = cmdObjectList.GetEnumerator())
			{
				while (enumerator.MoveNext())
				{
					object current = enumerator.get_Current();
					if (current.GetType() == typeof(ModContact))
					{
						list.Add(current);
					}
					else
					{
						if (current.GetType() == typeof(AddMsg))
						{
							list2.Add(current);
						}
						else
						{
							if (current.GetType() == typeof(ModChatRoomMember))
							{
								list3.Add(current);
							}
							else
							{
								list4.Add(current);
							}
						}
					}
				}
			}
			NetSceneNewSync.RespHandler(list);
			NetSceneNewSync.RespHandler(list2);
			NetSceneNewSync.RespHandler(list3);
			NetSceneNewSync.RespHandler(list4);
		}
		private void resetFlag()
		{
			NetSceneNewInit.mCmdList.Clear();
			this.mInitCount = 0;
			this.mProgress = 0u;
		}
		protected override void onFailed(NewInitRequest request, NewInitResponse response)
		{
			Log.smethod_1("NetSceneNewInit", "newInit doscene NewInit failed! network err");
			EventCenter.postEvent(EventConst.ON_NETSCENE_PROCESS_NEWINIT_ERR, null, null);
			NetSceneNewInit.mInitStatus = 0;
			this.resetFlag();
		}
		public bool saveUserInfo(NewInitRequest request, NewInitResponse response)
		{
			if (request != null && response != null)
			{
				NetSceneNewInit.mInitCurrentSynckey = response.CurrentSynckey.Buffer.ToByteArray();
				NetSceneNewInit.mInitMaxSynckey = response.MaxSynckey.Buffer.ToByteArray();
				byte[] mBytesSyncKeyBuf = NetSceneNewSync.mBytesSyncKeyBuf;
				NetSceneNewSync.mBytesSyncKeyBuf = NetSceneNewInit.mergeKeyBuf(mBytesSyncKeyBuf, response.CurrentSynckey.Buffer.ToByteArray());
				AccountMgr.getCurAccount().nNewUser = 0;
				AccountMgr.updateAccount();
				return true;
			}
			Log.smethod_5("NetSceneNewInit", "invalid NewInitReq or NewInitResp");
			return false;
		}
		private bool canContinue(NewInitResponse response)
		{
			return ((ulong)response.ContinueFlag & (ulong)((long)this.mSelector)) != 0uL && this.mInitCount < 50;
		}
		public bool needInit()
		{
			if (NetSceneNewSync.mBytesSyncKeyBuf != null)
			{
				if (NetSceneNewInit.mInitStatus == 1)
				{
					return false;
				}
			}
			return true;
		}
		public bool isInitDone()
		{
			return !this.needInit();
		}
		public bool isInitializing()
		{
			if (NetSceneNewInit.mInitStatus == 2)
			{
				Log.smethod_5("NetSceneNewInit", "mInitStatus =" + NetSceneNewInit.mInitStatus + ",do not need init");
				return true;
			}
			return false;
		}
		private static void onEventHandler(EventWatcher watcher, BaseEventArgs evtArgs)
		{
			Log.smethod_5("NetSceneNewInit", "receive ON_NETSCENE_AUTH_SUCCESS");
		}
		public static byte[] mergeKeyBuf(byte[] oldbuf, byte[] newbuf)
		{
			if (oldbuf == null || oldbuf.Length == 0)
			{
				return newbuf;
			}
			if (newbuf != null && newbuf.Length != 0)
			{
				SyncKey syncKey = null;
				byte[] result;
				try
				{
					syncKey = SyncKey.ParseFrom(oldbuf);
				}
				catch (Exception ex)
				{
					Log.smethod_1("NetSceneNewInit", "synckey oldbuf is invalid" + ex.get_Message());
					result = newbuf;
					return result;
				}
				SyncKey syncKey2 = null;
				try
				{
					syncKey2 = SyncKey.ParseFrom(newbuf);
					goto IL_7D;
				}
				catch (Exception ex2)
				{
					Log.smethod_1("NetSceneNewInit", "synckey newbuf is invalid" + ex2.get_Message());
					result = oldbuf;
				}
				return result;
				IL_7D:
				IList<KeyVal> keyList = syncKey.KeyList;
				IList<KeyVal> keyList2 = syncKey2.KeyList;
				Dictionary<uint, uint> dictionary = new Dictionary<uint, uint>();
				for (int i = 0; i < keyList.get_Count(); i++)
				{
					if (!dictionary.ContainsKey(keyList.get_Item(i).Key))
					{
						dictionary.Add(keyList.get_Item(i).Key, keyList.get_Item(i).Val);
					}
				}
				for (int j = 0; j < keyList2.get_Count(); j++)
				{
					if (dictionary.ContainsKey(keyList2.get_Item(j).Key))
					{
						if (keyList2.get_Item(j).Val > dictionary.get_Item(keyList2.get_Item(j).Key))
						{
							dictionary.set_Item(keyList2.get_Item(j).Key, keyList2.get_Item(j).Val);
						}
					}
					else
					{
						dictionary.Add(keyList2.get_Item(j).Key, keyList2.get_Item(j).Val);
					}
				}
				SyncKey syncKey3 = SyncKey.DefaultInstance;
				SyncKey.Builder builder = new SyncKey.Builder().SetKeyNum((uint)dictionary.get_Count());
				using (Dictionary<uint, uint>.Enumerator enumerator = dictionary.GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						KeyValuePair<uint, uint> current = enumerator.get_Current();
						KeyVal keyVal = KeyVal.CreateBuilder().SetKey(current.get_Key()).SetVal(current.get_Value()).Build();
						builder.KeyList.Add(keyVal);
					}
				}
				syncKey3 = builder.Build();
				return syncKey3.ToByteArray();
			}
			return oldbuf;
		}
	}
}
